// src/tts.cpp (最终修正版)

#include "tts.h" // 引入我们自己的头文件

// C/C++ 标准库
#include <atomic>
#include <cstdio>
#include <string>
#include <filesystem>
#include <unistd.h>    // for sleep()
#include <thread>      // +++ 新增：用于标准库的线程休眠
#include <chrono>      // +++ 新增：用于标准库的时间单位

// 第三方库
#include "miniaudio.h"  // 用于播放生成的提示音
#include "sparkchain.h" // 讯飞SDK
#include "sc_tts.h"     // 讯飞SDK

// 在此文件内使用 SparkChain 命名空间
using namespace SparkChain;

// --- 模块私有全局变量 ---
// 使用 static 关键字，使得这些变量仅在本文件(tts.cpp)内可见
static const char *APPID     = "xxxxxx";
static const char *APIKEY    = "xxxxxxxx";
static const char *APISECRET = "xxxxxxxxxxx";
static const char *WORKDIR   = "./";
static int logLevel          = 100; // 100 表示关闭日志

// 异步任务状态标志
static std::atomic_bool tts_task_finish(false);


// --- 模块私有实现 ---

/**
 * @brief 回调处理类，用于接收SDK返回的音频数据和错误信息
 */
class onlineTTSCallbacks : public TTSCallbacks {
    void onResult(TTSResult * result, void * usrTag) override {
        const char* currentAudioPath = static_cast<const char*>(usrTag);
        const char * data = result->data();
        int len           = result->len();
        int status        = result->status();

        FILE* file = fopen(currentAudioPath, "ab");
        if (file) {
            fwrite(data, 1, len, file);
            fclose(file);
        }

        if (status == 2) {
            tts_task_finish = true;
        }
    }

    void onError(TTSError * error, void * usrTag) override {
        printf("TTS请求出错, 错误码: %d, 错误信息:%s\n", error->code(), error->errMsg().c_str());
        tts_task_finish = true;
    }
};

/**
 * @brief [内部函数] 将文本转换为语音并保存到指定文件
 * @return 成功返回 true, 失败返回 false
 */
static bool textToSpeech(const char* text, const char* outputPath) {
    OnlineTTS tts("xiaoyan");
    tts.aue("lame");
    onlineTTSCallbacks cbs{};
    tts.registerCallbacks(&cbs);

    remove(outputPath);
    tts_task_finish = false;

    printf("开始合成: \"%s\" -> %s\n", text, outputPath);
    int ret = tts.arun(text, (void*)outputPath);
    if (ret != 0) {
        printf("TTS合成请求发送失败, 错误码: %d\n", ret);
        return false;
    }

    int times = 0;
    while (!tts_task_finish) {
        sleep(1);
        if (times++ > 20) {
            printf("TTS合成超时！\n");
            return false;
        }
    }
    printf("TTS合成流程结束。\n");
    return true;
}


// --- 公共接口函数实现 ---

bool initTTS_SDK() {
    SparkChainConfig *config = SparkChainConfig::builder();
    config->appID(APPID)->apiKey(APIKEY)->apiSecret(APISECRET)->workDir(WORKDIR)->logLevel(logLevel);
    int ret = SparkChain::init(config);
    if (ret != 0) {
        printf("TTS SDK 初始化失败!\n");
    }
    return (ret == 0);
}

void uninitTTS_SDK() {
    SparkChain::unInit();
}

bool playSongAnnouncement(const Song& song) {
    if (song.artist.empty() || song.displayName.empty()) {
        printf("Error: Song object is missing artist or displayName.\n");
        return false;
    }

    std::string announcementText = "现在为您播放由" + song.artist + "演唱的" + song.displayName;
    
    const std::string cacheDir = "tts_cache";
    if (!std::filesystem::exists(cacheDir)) {
        std::filesystem::create_directory(cacheDir);
    }
    std::string tipFileName = song.artist + "-" + song.displayName + "-tip.mp3";
    std::string tipFilePath = (std::filesystem::path(cacheDir) / tipFileName).string();

    if (!std::filesystem::exists(tipFilePath)) {
        printf("Tip sound not found, generating: %s\n", tipFilePath.c_str());
        if (!textToSpeech(announcementText.c_str(), tipFilePath.c_str())) {
            printf("Failed to generate tip sound.\n");
            return false;
        }
    }

    printf("Playing tip sound: %s\n", tipFilePath.c_str());
    ma_engine engine;
    if (ma_engine_init(NULL, &engine) != MA_SUCCESS) {
        printf("Failed to initialize tip audio engine.\n");
        return false;
    }

    ma_sound sound;
    if (ma_sound_init_from_file(&engine, tipFilePath.c_str(), 0, NULL, NULL, &sound) != MA_SUCCESS) {
        printf("Failed to init tip sound from file: %s\n", tipFilePath.c_str());
        ma_engine_uninit(&engine);
        return false;
    }
    
    ma_sound_start(&sound);
    while (ma_sound_at_end(&sound) == MA_FALSE) {
        // 使用标准库的休眠函数，替换 ma_sleep(100)
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    ma_sound_uninit(&sound);
    ma_engine_uninit(&engine);
    
    printf("Tip sound finished.\n");
    return true;
}